1 Quick Info

Coyotes (Canis lantrans) data on three individuals near Albany, NY, during the spring and summer of 2001, were used as examples for performing home range analyses.

Data comes from:

Bogan, D.A. 2004 Eastern coyote (Canis latrans) home range, habitat selection, and survival rates in the suburban Albany Pine Bush landscape of New York. MA Thesis. State University of New York at Albany.

2 Dataset

Convert Lat & Long to UTM Because I’m stubborn

Lets see if the dataset has any outliers, and get a rough view of the locations in a map.

Here, I will do a quick map on the three coyote individuals with a basemap from Open Street Map.

Both Beta and Omega had overlaping locations.

3 Home Range Analysis

Three basic types of home range analyses we will perform in this exercise: Minimum Convex Polygon (MCP), Kernel-Density Estimation (KDE), and Brownian Bridge Movement Model (BB).

MCP - draws the smallest polygon around points with all interior angles less than 180 degrees. MCPs are common estimators of home range, but can potentially include area not used by the animal and overestimate the home range

KDE - calculates the density of features in a neighborhood around those features.

BB - models movement of an individual

3.2 Kernel-Density Estimation

kde_raster <- function(filename){
  data <- read.csv(file = filename)
  x <- as.data.frame(data$utm.easting)
  y <- as.data.frame(data$utm.northing)
  xy <- c(x,y)
  data.proj <- SpatialPointsDataFrame(xy,data, proj4string = CRS("+proj=utm +zone=15 +south +ellps=WGS84 +units=m +no_defs"))
  xy <- SpatialPoints(data.proj@coords)
  kde<-kernelUD(xy, h="href", kern="bivnorm", grid=100)
  ver95 <- getverticeshr(kde, 95)
  ver75 <- getverticeshr(kde, 75)
  ver50 <- getverticeshr(kde, 50)
  kde.points <- cbind((data.frame(data.proj@coords)),data$individual.local.identifier)
  colnames(kde.points) <- c("x","y","identifier")
  kde.poly95 <- fortify(ver95, region = "id")
  kde.poly75 <- fortify(ver75, region = "id")
  kde.poly50 <- fortify(ver50, region = "id")
  units <- grid.text(paste(round(ver95$area,2)," ha"), x=0.85,  y=0.95,
                     gp=gpar(fontface=4, col="white", cex=0.9), draw = FALSE)
  kde.plot <- autoplot(raster_utm, expand = TRUE) + theme_bw() + theme(legend.position="none") +
    theme(panel.border = element_rect(colour = "black", fill=NA, size=1)) +
    geom_polygon(data=kde.poly95, aes(x=kde.poly95$long, y=kde.poly95$lat), alpha = 0.4, fill="red") +
    geom_polygon(data=kde.poly75, aes(x=kde.poly75$long, y=kde.poly75$lat), alpha = 0.4, fill="purple") +
    geom_polygon(data=kde.poly50, aes(x=kde.poly50$long, y=kde.poly50$lat), alpha = 0.4, fill="darkblue") +
    geom_point(data=kde.points, aes(x=x, y=y)) +
    labs(x="Easting (m)", y="Northing (m)", title=kde.points$identifier) +
    theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5)) + 
    annotation_custom(units)
  kde.plot
}
pblapply(files, kde_raster)

  |                                                  | 0 % ~calculating  
  |=================                                 | 33% ~01s          
  |==================================                | 67% ~01s          
  |==================================================| 100% elapsed=01s  
[[1]]

[[2]]

[[3]]

3.2.1 Brownian Bridge Movement

A <- read.csv("Alpha .csv")
date <- as.POSIXct(strptime(as.character(A$timestamp),"%Y-%m-%d %H:%M:%S", tz="Asia/Bangkok"))
A$date <- date
A.reloc <- cbind.data.frame(A$utm.easting, A$utm.northing,
                                as.vector(A$individual.local.identifier),
                                as.POSIXct(date))
colnames(A.reloc) <- c("x","y","id","date")
trajectory <- as.ltraj(A.reloc, date=date, id="Alpha")


sig1 <- liker(trajectory, sig2 = 58, rangesig1 = c(0, 5), plotit = FALSE)
opha.traj <- kernelbb(trajectory, sig1 = .1351, sig2 = 58, grid = 95)
bb_ver <- getverticeshr(opha.traj, 95)
bb_poly <- fortify(bb_ver, region = "id", 
                   proj4string = CRS("+proj=utm +zone=15 +south
                                     +ellps=WGS84 +units=m +no_defs"))
colnames(bb_poly) <- c("x","y","order","hole","piece","id","group")

# bb_image <- crop(opha.traj, bb_ver, 
#                  proj4string = CRS("+proj=utm +zone=15 +south 
#                                    +ellps=WGS84 +units=m +no_defs")) Crop Does not want to work

bb_units <- grid.text(paste(round(bb_ver$area,2)," ha"), x=0.85,  y=0.95,
                      gp=gpar(fontface=4, col="white", cex=0.9), draw = FALSE)
bb.plot <- autoplot(raster_utm, expand = TRUE) + theme_bw() + theme(legend.position="none") +
  coord_fixed(xlim = c(min(A$utm.easting), max(A$utm.easting)), ylim = c(min(A$utm.northing), max(A$utm.northing)))+
  theme(panel.border = element_rect(colour = "black", fill=NA, size=1)) +
  geom_tile(data=opha.traj, 
            aes(x=opha.traj@coords[,1], y=opha.traj@coords[,2],
                fill = opha.traj@data$ud)) +
  geom_polygon(data=bb_poly, aes(x=x, y=y, group = group), color = "white", fill = NA) +
  scale_fill_viridis_c(option = "inferno") + annotation_custom(bb_units) +
  labs(x="Easting (m)", y="Northing (m)", title="Alpha") +
  theme(legend.position="none", plot.title = element_text(face = "bold", hjust = 0.5))
bb.plot

3.3 Animate Trajectory Data

Here is my attempt at creating an animation of the individual “Alpha”’s movement from April to July in 2001 in Albany, NY, USA. Data was collected by radio telemetry.

LS0tDQp0aXRsZTogIkhvbWUgUmFuZ2UgQ3Jhc2ggQ291cnNlIg0KYXV0aG9yOiAiSmFjayBLYXVwaHVzbWFuIg0KZGF0ZTogIjExLzEzLzIwMTkiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgaGlnaGxpZ2h0OiBicmVlemVkYXJrDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICByb3dzLnByaW50OiAxMA0KICAgIHRoZW1lOiBjb3Ntbw0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICAgICAgc21vb3RoX3Njcm9sbDogeWVzDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgdG9jOiB5ZXMNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogNDBweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQo8L3N0eWxlPg0KLS0tDQoNCmBgYHtyIFBhY2thZ2VzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KcGFja2FnZXM8LWMoImFkZWhhYml0YXRIUiIsImRhdGEudGFibGUiLCJnZ2ZvcnRpZnkiLCJncmlkIiwibW92ZSIsIm1vdmVWaXMiLCJPcGVuU3RyZWV0TWFwIiwicGJhcHBseSIsInBsb3RseSIsInJnZGFsIiwic3AiLCJ0aWR5dmVyc2UiLCJ2aXJpZGlzIikNCnNhcHBseShwYWNrYWdlcywgcmVxdWlyZSwgY2hhcmFjdGVyLm9ubHk9VCkNCmxpYnJhcnkockphdmEpDQpsaWJyYXJ5KE9wZW5TdHJlZXRNYXApDQpsaWJyYXJ5IChyYXN0ZXIpDQpgYGANCiMgUXVpY2sgSW5mbw0KDQpDb3lvdGVzICgqQ2FuaXMgbGFudHJhbnMqKSBkYXRhIG9uIHRocmVlIGluZGl2aWR1YWxzIG5lYXIgQWxiYW55LCBOWSwgZHVyaW5nIHRoZSBzcHJpbmcgYW5kIHN1bW1lciBvZiAyMDAxLCB3ZXJlIHVzZWQgYXMgZXhhbXBsZXMgZm9yIHBlcmZvcm1pbmcgaG9tZSByYW5nZSBhbmFseXNlcy4NCg0KRGF0YSBjb21lcyBmcm9tOg0KDQpCb2dhbiwgRC5BLiAyMDA0IEVhc3Rlcm4gY295b3RlIChDYW5pcyBsYXRyYW5zKSBob21lIHJhbmdlLCBoYWJpdGF0IHNlbGVjdGlvbiwgYW5kIHN1cnZpdmFsIHJhdGVzIGluIHRoZSBzdWJ1cmJhbiBBbGJhbnkgUGluZSBCdXNoIGxhbmRzY2FwZSBvZiBOZXcgWW9yay4gTUEgVGhlc2lzLiBTdGF0ZSBVbml2ZXJzaXR5IG9mIE5ldyBZb3JrIGF0IEFsYmFueS4NCg0KDQohW10oZGF0YS9pbWFnZS5qcGcpIA0KDQoNCiMgRGF0YXNldCANCmBgYHtyfQ0KY295b3RlPC1yZWFkLmNzdigiZGF0YS9jb3lvdGUuY3N2IikNCmhlYWQoY295b3RlKQ0KYGBgDQoNCkNvbnZlcnQgTGF0ICYgTG9uZyB0byBVVE0gQmVjYXVzZSBJJ20gc3R1YmJvcm4NCg0KYGBge3J9DQp6b25lMTg8LWRhdGEuZnJhbWUoY295b3RlJGxvY2F0aW9uLmxvbmcsIGNveW90ZSRsb2NhdGlvbi5sYXQpDQpuYW1lcyh6b25lMTgpPC1jKCJYIiwgIlkiKQ0Kem9uZTE4PC1hcy5tYXRyaXgoem9uZTE4KQ0KVVRNPC1wcm9qZWN0KHpvbmUxOCwgIitwcm9qPXV0bSArem9uZT0xOCBlbGxwcz1XR1M4NCIpDQpVVE08LWRhdGEuZnJhbWUoVVRNKQ0KbmFtZXMoVVRNKTwtYygidXRtLmVhc3RpbmciLCAidXRtLm5vcnRoaW5nIikNCmNveW90ZTwtY2JpbmQoY295b3RlLCBVVE0pDQpgYGANCg0KDQpMZXRzIHNlZSBpZiB0aGUgZGF0YXNldCBoYXMgYW55IG91dGxpZXJzLCBhbmQgZ2V0IGEgcm91Z2ggdmlldyBvZiB0aGUgbG9jYXRpb25zIGluIGEgbWFwLg0KDQpgYGB7cn0NCm1hcDEgPC0gZ2dwbG90KCkgKyBnZW9tX3BvaW50KGRhdGE9Y295b3RlLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHV0bS5lYXN0aW5nLCB1dG0ubm9ydGhpbmcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1pbmRpdmlkdWFsLmxvY2FsLmlkZW50aWZpZXIpKSArDQogICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHg9IkVhc3RpbmciLCB5PSAiTm9ydGhpbmciKSArDQogICAgICAgICAgICAgICAgICAgICAgICBndWlkZXMoY29sb3I9Z3VpZGVfbGVnZW5kKCJJZGVudGlmaWVyIikpDQoNCmdncGxvdGx5KG1hcDEpDQoNCmBgYA0KSGVyZSwgSSB3aWxsIGRvIGEgcXVpY2sgbWFwIG9uIHRoZSB0aHJlZSBjb3lvdGUgaW5kaXZpZHVhbHMgd2l0aCBhIGJhc2VtYXAgZnJvbSBPcGVuIFN0cmVldCBNYXAuIA0KDQpgYGB7ciBpbWFnZXJ5LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9DQp1dG1fcG9pbnRzIDwtIGNiaW5kKGNveW90ZSR1dG0uZWFzdGluZywgY295b3RlJHV0bS5ub3J0aGluZykNCnV0bV9sb2NhdGlvbnMgPC0gU3BhdGlhbFBvaW50cyh1dG1fcG9pbnRzLCANCiAgICAgICAgICAgICAgICAgcHJvajRzdHJpbmc9Q1JTKCIrcHJvaj11dG0gK3pvbmU9MTggK2RhdHVtPVdHUzg0IikpDQpwcm9qX2xhdC5sb24gPC0gYXMuZGF0YS5mcmFtZShzcFRyYW5zZm9ybSgNCiAgICAgICAgICAgICAgICB1dG1fbG9jYXRpb25zLCBDUlMoIitwcm9qPWxvbmdsYXQgK2RhdHVtPVdHUzg0IikpKQ0KY29sbmFtZXMocHJval9sYXQubG9uKSA8LSBjKCJ4IiwieSIpDQpyYXN0ZXIgPC0gb3Blbm1hcChjKG1heChwcm9qX2xhdC5sb24keSkrMC4wMSwgbWluKHByb2pfbGF0LmxvbiR4KS0wLjAxKSwgDQogICAgICAgICAgICAgICAgICBjKG1pbihwcm9qX2xhdC5sb24keSktMC4wMSwgbWF4KHByb2pfbGF0LmxvbiR4KSswLjAxKSwgDQogICAgICAgICAgICAgICAgICB0eXBlID0gImJpbmciKQ0KcmFzdGVyX3V0bSA8LSBvcGVucHJvaihyYXN0ZXIsIA0KICAgICAgICAgICAgICBwcm9qZWN0aW9uID0gIitwcm9qPXV0bSArem9uZT0xOCArZWxscHM9V0dTODQgK3VuaXRzPW0gK25vX2RlZnMiKQ0KDQoNCmF1dG9wbG90KHJhc3Rlcl91dG0sIGV4cGFuZCA9IFRSVUUpICsgdGhlbWVfYncoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKw0KICB0aGVtZShwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkgKw0KICBnZW9tX3BvaW50KGRhdGE9Y295b3RlLCBhZXModXRtLmVhc3RpbmcsdXRtLm5vcnRoaW5nLA0KICAgICAgICAgICAgIGNvbG9yPWluZGl2aWR1YWwubG9jYWwuaWRlbnRpZmllciksIHNpemUgPSAzLCBhbHBoYSA9IDAuOCkgKw0KICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQiKSkgKyBsYWJzKHg9IkVhc3RpbmciLA0KICAgICAgICB5PSJOb3J0aGluZyIpICsgZ3VpZGVzKGNvbG9yPWd1aWRlX2xlZ2VuZCgiSWRlbnRpZmllciIpKQ0KYGBgDQpCb3RoIEJldGEgYW5kIE9tZWdhIGhhZCBvdmVybGFwaW5nIGxvY2F0aW9ucy4NCg0KDQpgYGB7ciBsYXBwbHkgZnVuY3Rpb24sIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQ0KbGFwcGx5KHNwbGl0KGNveW90ZSwgY295b3RlJGluZGl2aWR1YWwubG9jYWwuaWRlbnRpZmllciksIA0KICAgICAgIGZ1bmN0aW9uKHgpd3JpdGUuY3N2KHgsIGZpbGUgPSBwYXN0ZSh4JGluZGl2aWR1YWwubG9jYWwuaWRlbnRpZmllclsxXSwiLmNzdiIpLCByb3cubmFtZXMgPSBGQUxTRSkpDQpgYGANCg0KYGBge3IgbGlzdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdoaWRlJ30NCmZpbGVzIDwtIGxpc3QuZmlsZXMocGF0aCA9ICIuIiwgcGF0dGVybiA9IiouY3N2IiAsIGZ1bGwubmFtZXMgPSBUUlVFKQ0KYGBgDQoNCiMgSG9tZSBSYW5nZSBBbmFseXNpcw0KDQpUaHJlZSBiYXNpYyB0eXBlcyBvZiBob21lIHJhbmdlIGFuYWx5c2VzIHdlIHdpbGwgcGVyZm9ybSBpbiB0aGlzIGV4ZXJjaXNlOiBNaW5pbXVtIENvbnZleCBQb2x5Z29uIChNQ1ApLCBLZXJuZWwtRGVuc2l0eSBFc3RpbWF0aW9uIChLREUpLCBhbmQgQnJvd25pYW4gQnJpZGdlIE1vdmVtZW50IE1vZGVsIChCQikuDQoNCk1DUCAtIGRyYXdzIHRoZSBzbWFsbGVzdCBwb2x5Z29uIGFyb3VuZCBwb2ludHMgd2l0aCBhbGwgaW50ZXJpb3IgYW5nbGVzIGxlc3MgdGhhbiAxODAgZGVncmVlcy4gTUNQcyBhcmUgY29tbW9uIGVzdGltYXRvcnMgb2YgaG9tZSByYW5nZSwgYnV0IGNhbiBwb3RlbnRpYWxseSBpbmNsdWRlIGFyZWEgbm90IHVzZWQgYnkgdGhlIGFuaW1hbCBhbmQgb3ZlcmVzdGltYXRlIHRoZSBob21lIHJhbmdlDQoNCktERSAtIGNhbGN1bGF0ZXMgdGhlIGRlbnNpdHkgb2YgZmVhdHVyZXMgaW4gYSBuZWlnaGJvcmhvb2QgYXJvdW5kIHRob3NlIGZlYXR1cmVzLg0KDQpCQiAtIG1vZGVscyBtb3ZlbWVudCBvZiBhbiBpbmRpdmlkdWFsDQoNCiMjIE1DUCBBbmFseXNpcw0KDQpgYGB7ciBNQ1AgcGxvdCwgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD02LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbWNwX3Jhc3RlciA8LSBmdW5jdGlvbihmaWxlbmFtZSl7DQogIGRhdGEgPC0gcmVhZC5jc3YoZmlsZSA9IGZpbGVuYW1lKQ0KICB4IDwtIGFzLmRhdGEuZnJhbWUoZGF0YSR1dG0uZWFzdGluZykNCiAgeSA8LSBhcy5kYXRhLmZyYW1lKGRhdGEkdXRtLm5vcnRoaW5nKQ0KICB4eSA8LSBjKHgseSkNCiAgZGF0YS5wcm9qIDwtIFNwYXRpYWxQb2ludHNEYXRhRnJhbWUoeHksZGF0YSwgcHJvajRzdHJpbmcgPSBDUlMoIitwcm9qPXV0bSArem9uZT0xOCArZWxscHM9V0dTODQgK3VuaXRzPW0gK25vX2RlZnMiKSkNCiAgeHkgPC0gU3BhdGlhbFBvaW50cyhkYXRhLnByb2pAY29vcmRzKQ0KICBtY3Aub3V0IDwtIG1jcCh4eSwgcGVyY2VudD0xMDAsIHVub3V0PSJoYSIpDQogIG1jcC5wb2ludHMgPC0gY2JpbmQoKGRhdGEuZnJhbWUoeHkpKSxkYXRhJGluZGl2aWR1YWwubG9jYWwuaWRlbnRpZmllcikNCiAgY29sbmFtZXMobWNwLnBvaW50cykgPC0gYygieCIsInkiLCAiaWRlbnRpZmllciIpDQogIG1jcC5wb2x5IDwtIGZvcnRpZnkobWNwLm91dCwgcmVnaW9uID0gImlkIikNCiAgdW5pdHMgPC0gZ3JpZC50ZXh0KHBhc3RlKHJvdW5kKG1jcC5vdXRAZGF0YSRhcmVhLDIpLCJoYSIpLCB4PTAuODUsICB5PTAuOTUsDQogICAgICAgICAgICAgICAgICAgICBncD1ncGFyKGZvbnRmYWNlPTQsIGNvbD0id2hpdGUiLCBjZXg9MC45KSwgZHJhdyA9IEZBTFNFKQ0KICBtY3AucGxvdCA8LSBhdXRvcGxvdChyYXN0ZXJfdXRtLCBleHBhbmQgPSBUUlVFKSArIHRoZW1lX2J3KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArDQogICAgdGhlbWUocGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIsIGZpbGw9TkEsIHNpemU9MSkpICsNCiAgICBnZW9tX3BvbHlnb24oZGF0YT1tY3AucG9seSwgYWVzKHg9bWNwLnBvbHkkbG9uZywgeT1tY3AucG9seSRsYXQpLCBhbHBoYT0wLjgpICsNCiAgICBnZW9tX3BvaW50KGRhdGE9bWNwLnBvaW50cywgYWVzKHg9eCwgeT15KSkgKyANCiAgICBsYWJzKHg9IkVhc3RpbmcgKG0pIiwgeT0iTm9ydGhpbmcgKG0pIiwgdGl0bGU9bWNwLnBvaW50cyRpZGVudGlmaWVyKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSkpICsgDQogICAgYW5ub3RhdGlvbl9jdXN0b20odW5pdHMpDQogIG1jcC5wbG90DQp9DQoNCnBibGFwcGx5KGZpbGVzLCBtY3BfcmFzdGVyKQ0KYGBgDQoNCiMjIEtlcm5lbC1EZW5zaXR5IEVzdGltYXRpb24NCg0KYGBge3IgS0RFIHBsb3QsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89VFJVRSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9Nn0NCmtkZV9yYXN0ZXIgPC0gZnVuY3Rpb24oZmlsZW5hbWUpew0KICBkYXRhIDwtIHJlYWQuY3N2KGZpbGUgPSBmaWxlbmFtZSkNCiAgeCA8LSBhcy5kYXRhLmZyYW1lKGRhdGEkdXRtLmVhc3RpbmcpDQogIHkgPC0gYXMuZGF0YS5mcmFtZShkYXRhJHV0bS5ub3J0aGluZykNCiAgeHkgPC0gYyh4LHkpDQogIGRhdGEucHJvaiA8LSBTcGF0aWFsUG9pbnRzRGF0YUZyYW1lKHh5LGRhdGEsIHByb2o0c3RyaW5nID0gQ1JTKCIrcHJvaj11dG0gK3pvbmU9MTUgK3NvdXRoICtlbGxwcz1XR1M4NCArdW5pdHM9bSArbm9fZGVmcyIpKQ0KICB4eSA8LSBTcGF0aWFsUG9pbnRzKGRhdGEucHJvakBjb29yZHMpDQogIGtkZTwta2VybmVsVUQoeHksIGg9ImhyZWYiLCBrZXJuPSJiaXZub3JtIiwgZ3JpZD0xMDApDQogIHZlcjk1IDwtIGdldHZlcnRpY2VzaHIoa2RlLCA5NSkNCiAgdmVyNzUgPC0gZ2V0dmVydGljZXNocihrZGUsIDc1KQ0KICB2ZXI1MCA8LSBnZXR2ZXJ0aWNlc2hyKGtkZSwgNTApDQogIGtkZS5wb2ludHMgPC0gY2JpbmQoKGRhdGEuZnJhbWUoZGF0YS5wcm9qQGNvb3JkcykpLGRhdGEkaW5kaXZpZHVhbC5sb2NhbC5pZGVudGlmaWVyKQ0KICBjb2xuYW1lcyhrZGUucG9pbnRzKSA8LSBjKCJ4IiwieSIsImlkZW50aWZpZXIiKQ0KICBrZGUucG9seTk1IDwtIGZvcnRpZnkodmVyOTUsIHJlZ2lvbiA9ICJpZCIpDQogIGtkZS5wb2x5NzUgPC0gZm9ydGlmeSh2ZXI3NSwgcmVnaW9uID0gImlkIikNCiAga2RlLnBvbHk1MCA8LSBmb3J0aWZ5KHZlcjUwLCByZWdpb24gPSAiaWQiKQ0KICB1bml0cyA8LSBncmlkLnRleHQocGFzdGUocm91bmQodmVyOTUkYXJlYSwyKSwiIGhhIiksIHg9MC44NSwgIHk9MC45NSwNCiAgICAgICAgICAgICAgICAgICAgIGdwPWdwYXIoZm9udGZhY2U9NCwgY29sPSJ3aGl0ZSIsIGNleD0wLjkpLCBkcmF3ID0gRkFMU0UpDQogIGtkZS5wbG90IDwtIGF1dG9wbG90KHJhc3Rlcl91dG0sIGV4cGFuZCA9IFRSVUUpICsgdGhlbWVfYncoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsNCiAgICB0aGVtZShwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkgKw0KICAgIGdlb21fcG9seWdvbihkYXRhPWtkZS5wb2x5OTUsIGFlcyh4PWtkZS5wb2x5OTUkbG9uZywgeT1rZGUucG9seTk1JGxhdCksIGFscGhhID0gMC40LCBmaWxsPSJyZWQiKSArDQogICAgZ2VvbV9wb2x5Z29uKGRhdGE9a2RlLnBvbHk3NSwgYWVzKHg9a2RlLnBvbHk3NSRsb25nLCB5PWtkZS5wb2x5NzUkbGF0KSwgYWxwaGEgPSAwLjQsIGZpbGw9InB1cnBsZSIpICsNCiAgICBnZW9tX3BvbHlnb24oZGF0YT1rZGUucG9seTUwLCBhZXMoeD1rZGUucG9seTUwJGxvbmcsIHk9a2RlLnBvbHk1MCRsYXQpLCBhbHBoYSA9IDAuNCwgZmlsbD0iZGFya2JsdWUiKSArDQogICAgZ2VvbV9wb2ludChkYXRhPWtkZS5wb2ludHMsIGFlcyh4PXgsIHk9eSkpICsNCiAgICBsYWJzKHg9IkVhc3RpbmcgKG0pIiwgeT0iTm9ydGhpbmcgKG0pIiwgdGl0bGU9a2RlLnBvaW50cyRpZGVudGlmaWVyKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSkpICsgDQogICAgYW5ub3RhdGlvbl9jdXN0b20odW5pdHMpDQogIGtkZS5wbG90DQp9DQpwYmxhcHBseShmaWxlcywga2RlX3Jhc3RlcikNCmBgYA0KDQojIyMgQnJvd25pYW4gQnJpZGdlIE1vdmVtZW50IA0KDQoNCmBgYHtyIGJiIHBsb3QsIGVjaG89VFJVRSwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCkEgPC0gcmVhZC5jc3YoIkFscGhhIC5jc3YiKQ0KZGF0ZSA8LSBhcy5QT1NJWGN0KHN0cnB0aW1lKGFzLmNoYXJhY3RlcihBJHRpbWVzdGFtcCksIiVZLSVtLSVkICVIOiVNOiVTIiwgdHo9IkFzaWEvQmFuZ2tvayIpKQ0KQSRkYXRlIDwtIGRhdGUNCkEucmVsb2MgPC0gY2JpbmQuZGF0YS5mcmFtZShBJHV0bS5lYXN0aW5nLCBBJHV0bS5ub3J0aGluZywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXMudmVjdG9yKEEkaW5kaXZpZHVhbC5sb2NhbC5pZGVudGlmaWVyKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXMuUE9TSVhjdChkYXRlKSkNCmNvbG5hbWVzKEEucmVsb2MpIDwtIGMoIngiLCJ5IiwiaWQiLCJkYXRlIikNCnRyYWplY3RvcnkgPC0gYXMubHRyYWooQS5yZWxvYywgZGF0ZT1kYXRlLCBpZD0iQWxwaGEiKQ0KDQoNCnNpZzEgPC0gbGlrZXIodHJhamVjdG9yeSwgc2lnMiA9IDU4LCByYW5nZXNpZzEgPSBjKDAsIDUpLCBwbG90aXQgPSBGQUxTRSkNCm9waGEudHJhaiA8LSBrZXJuZWxiYih0cmFqZWN0b3J5LCBzaWcxID0gLjEzNTEsIHNpZzIgPSA1OCwgZ3JpZCA9IDk1KQ0KYmJfdmVyIDwtIGdldHZlcnRpY2VzaHIob3BoYS50cmFqLCA5NSkNCmJiX3BvbHkgPC0gZm9ydGlmeShiYl92ZXIsIHJlZ2lvbiA9ICJpZCIsIA0KICAgICAgICAgICAgICAgICAgIHByb2o0c3RyaW5nID0gQ1JTKCIrcHJvaj11dG0gK3pvbmU9MTUgK3NvdXRoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgK2VsbHBzPVdHUzg0ICt1bml0cz1tICtub19kZWZzIikpDQpjb2xuYW1lcyhiYl9wb2x5KSA8LSBjKCJ4IiwieSIsIm9yZGVyIiwiaG9sZSIsInBpZWNlIiwiaWQiLCJncm91cCIpDQoNCiMgYmJfaW1hZ2UgPC0gY3JvcChvcGhhLnRyYWosIGJiX3ZlciwgDQojICAgICAgICAgICAgICAgICAgcHJvajRzdHJpbmcgPSBDUlMoIitwcm9qPXV0bSArem9uZT0xNSArc291dGggDQojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgK2VsbHBzPVdHUzg0ICt1bml0cz1tICtub19kZWZzIikpIENyb3AgRG9lcyBub3Qgd2FudCB0byB3b3JrDQoNCmJiX3VuaXRzIDwtIGdyaWQudGV4dChwYXN0ZShyb3VuZChiYl92ZXIkYXJlYSwyKSwiIGhhIiksIHg9MC44NSwgIHk9MC45NSwNCiAgICAgICAgICAgICAgICAgICAgICBncD1ncGFyKGZvbnRmYWNlPTQsIGNvbD0id2hpdGUiLCBjZXg9MC45KSwgZHJhdyA9IEZBTFNFKQ0KYmIucGxvdCA8LSBhdXRvcGxvdChyYXN0ZXJfdXRtLCBleHBhbmQgPSBUUlVFKSArIHRoZW1lX2J3KCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArDQogIGNvb3JkX2ZpeGVkKHhsaW0gPSBjKG1pbihBJHV0bS5lYXN0aW5nKSwgbWF4KEEkdXRtLmVhc3RpbmcpKSwgeWxpbSA9IGMobWluKEEkdXRtLm5vcnRoaW5nKSwgbWF4KEEkdXRtLm5vcnRoaW5nKSkpKw0KICB0aGVtZShwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkgKw0KICBnZW9tX3RpbGUoZGF0YT1vcGhhLnRyYWosIA0KICAgICAgICAgICAgYWVzKHg9b3BoYS50cmFqQGNvb3Jkc1ssMV0sIHk9b3BoYS50cmFqQGNvb3Jkc1ssMl0sDQogICAgICAgICAgICAgICAgZmlsbCA9IG9waGEudHJhakBkYXRhJHVkKSkgKw0KICBnZW9tX3BvbHlnb24oZGF0YT1iYl9wb2x5LCBhZXMoeD14LCB5PXksIGdyb3VwID0gZ3JvdXApLCBjb2xvciA9ICJ3aGl0ZSIsIGZpbGwgPSBOQSkgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhvcHRpb24gPSAiaW5mZXJubyIpICsgYW5ub3RhdGlvbl9jdXN0b20oYmJfdW5pdHMpICsNCiAgbGFicyh4PSJFYXN0aW5nIChtKSIsIHk9Ik5vcnRoaW5nIChtKSIsIHRpdGxlPSJBbHBoYSIpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSkpDQpiYi5wbG90DQpgYGANCiMjIEFuaW1hdGUgVHJhamVjdG9yeSBEYXRhDQoNCkhlcmUgaXMgbXkgYXR0ZW1wdCBhdCBjcmVhdGluZyBhbiBhbmltYXRpb24gb2YgdGhlIGluZGl2aWR1YWwgIkFscGhhIidzIG1vdmVtZW50IGZyb20gQXByaWwgdG8gSnVseSBpbiAyMDAxIGluIEFsYmFueSwgTlksIFVTQS4gRGF0YSB3YXMgY29sbGVjdGVkIGJ5IHJhZGlvIHRlbGVtZXRyeS4NCg0KYGBge3IgbW92ZSwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30NCkEubW92ZSA8LSBtb3ZlKHg9QSRsb2NhdGlvbi5sb25nLCANCiAgICAgICAgICAgICB5PUEkbG9jYXRpb24ubGF0LCANCiAgICAgICAgICAgICB0aW1lPWFzLlBPU0lYY3QoQSR0aW1lc3RhbXAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQ9IiVZLSVtLSVkICVIOiVNOiVTIiwgdHo9IkFzaWEvQmFuZ2tvayIpLCANCiAgICAgICAgICAgICBwcm9qPUNSUygiK3Byb2o9bG9uZ2xhdCArZWxscHM9V0dTODQgK2RhdHVtPVdHUzg0IiksDQogICAgICAgICAgICAgZGF0YT1BLCBhbmltYWw9QSRpbmRpdmlkdWFsLmxvY2FsLmlkZW50aWZpZXIsIA0KICAgICAgICAgICAgIHNlbnNvcj1BJHNlbnNvci50eXBlKQ0KDQptb3ZlbWVudDEgPC0gYWxpZ25fbW92ZShBLm1vdmUsIHJlcyA9ICJtYXgiLCBkaWdpdCA9IDAsIHVuaXQgPSAic2VjcyIpDQoNCg0KZnJhbWVzIDwtIGZyYW1lc19zcGF0aWFsKG1vdmVtZW50MSwgcGF0aF9jb2xvdXJzID0gInJlZCIsdGFpbF9sZW5ndGggPSAyOSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBtYXBfc2VydmljZSA9ICJvc20iLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gMC41KSAlPiUgDQogIGFkZF9sYWJlbHMoeCA9ICJMb25naXR1ZGUiLCB5ID0gIkxhdGl0dWRlIikgJT4lDQogIGFkZF9ub3J0aGFycm93KCkgJT4lIA0KICBhZGRfc2NhbGViYXIoKSAlPiUgDQogIGFkZF90aW1lc3RhbXBzKG1vdmVtZW50MSwgdHlwZSA9ICJsYWJlbCIpICU+JSANCiAgYWRkX3Byb2dyZXNzKCkNCg0KYW5pbWF0ZV9mcmFtZXMoZnJhbWVzLCBmcHMgPSA1LCBvdmVyd3JpdGUgPSBUUlVFLA0KICAgICAgICAgICAgICAgb3V0X2ZpbGUgPSAiLi9tb3ZlVmlzLTVmcHMuZ2lmIikNCmBgYA0KIVtdKC4vbW92ZVZpcy01ZnBzLmdpZiAiUmVsb2NhdGlvbiBBbmltYXRpb24gZm9yIEFscGhhIikNCg0K